<template>
  <div class="vc-editable-input">
    <input
        :aria-labelledby="labelId"
        class="vc-input__input"
        v-model="val"
        @keydown="handleKeyDown"
        @input="update"
        ref="input"
    >
    <span :for="label" class="vc-input__label" :id="labelId">{{ labelSpanText }}</span>
    <span class="vc-input__desc">{{ desc }}</span>
  </div>
</template>

<script lang="ts">
import { computed, defineComponent, Ref, ref } from 'vue'

export default defineComponent({
  name: 'EditableInput',
  props: {
    label: {
      type: String,
      required: true,
    },
    labelText: String,
    desc: String,
    value: [String, Number],
    max: Number,
    min: Number,
    arrowOffset: {
      type: Number,
      default: 1,
    },
  },
  emits: ['change'],
  setup(props, { emit }) {
    const input: Ref = ref(null)

    const val = computed({
      get() {
        return props.value as number
      },
      set(v: number) {
        // TODO: min
        if (!(typeof props.max === 'undefined') && +v > props.max) {
          input.value.value = props.max
        } else {
          return v
        }
      },
    })

    const handleChange = (newVal: number | string) => {
      let data: any = {}
      data[props.label] = newVal
      if (typeof data.hex === 'undefined' && typeof data['#'] === 'undefined') {
        emit('change', data)
      } else if ((newVal as string).length > 5) {
        emit('change', data)
      }
    }

    const handleKeyDown = (e: any) => {
      let computedVal = val.value
      let number = Number(val)

      if (number) {
        let amount = props.arrowOffset || 1

        // Up
        if (e.keyCode === 38) {
          computedVal = number + amount
          handleChange(computedVal)
          e.preventDefault()
        }

        // Down
        if (e.keyCode === 40) {
          computedVal = number - amount
          handleChange(computedVal)
          e.preventDefault()
        }
      }
    }

    return {
      input,
      val,
      labelId: computed(() => `input__label__${props.label}__${Math.random().toString().slice(2, 5)}`),
      labelSpanText: computed(() => props.labelText || props.label),
      handleKeyDown,
      update(e: any) {
        handleChange(e.target.value)
      },
    }
  },
})
</script>